<!-- 创建商品 -->
<template>
  <div>
    <!-- 商品（Spu）介绍 -->
    <el-card>
      <h4 style="margin-bottom: 10px">商品（Spu）介绍</h4>
      <el-form
        label-width="150px"
        ref="formRef"
        :rules="rulesA"
        :model="submitData"
        status-icon
      >
        <el-form-item prop="title" label="商品名称">
          <el-input v-model="submitData.title" />
        </el-form-item>
        <el-form-item label="原始价格" prop="originalPrice">
          <el-input v-model="submitData.originalPrice">
            <template #append>元</template>
          </el-input>
        </el-form-item>
        <el-form-item label="当前价格" prop="price">
          <el-input v-model="submitData.price">
            <template #append>元</template>
          </el-input>
        </el-form-item>
        <el-form-item label="VIP价格" prop="vipPrice">
          <el-input v-model="submitData.vipPrice">
            <template #append>元</template>
          </el-input>
        </el-form-item>
        <el-form-item label="剩余库存">
          <el-input disabled v-model="submitData.stock" />
        </el-form-item>
        <el-form-item label="运费模板">
          <el-select
            v-model="submitData.freightTemplateId"
            clearable
            @focus="getFreight"
            placeholder="选择商品运费模板"
          >
            <el-option
              v-for="item in freightList"
              :key="item.id"
              :label="item.title"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="是否在售" prop="status">
          <el-radio-group v-model="submitData.status">
            <el-radio :label="1">在售</el-radio>
            <el-radio :label="0">下架</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="商品图片">
          <el-upload
            v-model:file-list="imgList"
            :headers="{ AdminToken: token }"
            :action="action"
            :on-success="handleSuccess"
            :on-remove="handleRemove"
            :limit="5"
            list-type="picture-card"
          >
            <el-icon>
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="商品单位" prop="unit">
          <el-input v-model="submitData.unit" placeholder="件/个/盒" />
        </el-form-item>
        <el-form-item label="所属类目">
          <el-cascader
            clearable
            @focus="getCategory"
            v-model="submitData.categoryId"
            :props="props"
            placeholder="请选择类目"
            :options="categoryList"
            :show-all-levels="false"
          />
        </el-form-item>
        <el-form-item label="商品简介">
          <el-input v-model="submitData.description" />
        </el-form-item>
        <el-form-item label="商品详细介绍" prop="detail">
          <RichText v-model="submitData.detail"></RichText>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- 商品参数 -->
    <el-card>
      <el-space direction="vertical" alignment="left">
        <h4>商品参数</h4>
        <el-button type="primary" plain @click="dialogA = true">添加</el-button>
      </el-space>
      <el-table :data="submitData.attributeList">
        <el-table-column label="商品参数名称" prop="attribute" align="center" />
        <el-table-column label="商品参数值" prop="value" align="center" />
        <el-table-column label="操作" align="center">
          <template #default="scope">
            <el-button type="danger" @click="deleParameter(scope.$index)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- 商品参数弹窗 -->
      <el-dialog
        v-model="dialogA"
        title="设置商品参数"
        width="700px"
        destroy-on-close
      >
        <el-form
          ref="attrForm"
          :model="attrItem"
          :rules="rulesB"
          :label-width="150"
          status-icon
        >
          <el-form-item label="商品参数名称" prop="attribute">
            <el-input v-model.trim="attrItem.attribute" />
          </el-form-item>
          <el-form-item label="商品参数值" prop="value">
            <el-input v-model.trim="attrItem.value" />
          </el-form-item>
        </el-form>
        <template #footer>
          <span>
            <el-button @click="dialogA = false">取消</el-button>
            <el-button type="primary" @click="addParameter('attrForm')"
              >确定</el-button
            >
          </span>
        </template>
      </el-dialog>
    </el-card>
    <!-- 规格维度 -->
    <el-card>
      <el-space direction="vertical" alignment="left">
        <h4>规格维度</h4>
        <el-button
          type="primary"
          plain
          @click="
            () => {
              parameterStatus = 0;
              dialogB = true;
            }
          "
          >添加</el-button
        >
      </el-space>
      <el-table :data="submitData.specificationList">
        <el-table-column label="维度id" align="center" />
        <el-table-column label="维度名称" prop="title" align="center" />
        <el-table-column label="创建时间" prop="gmtCreate" align="center">
          <template #default="scope">
            {{ new Date(scope.row.gmtCreate).computeDate() }}
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template #default="scope">
            <el-button
              type="primary"
              @click="
                () => {
                  Object.assign(specification, scope.row);
                  parameterIndex = scope.$index;
                  parameterStatus = 1;
                  dialogB = true;
                }
              "
              >修改</el-button
            >
            <el-button type="danger" @click="delelSpecifica(scope.$index)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- 规格维度弹窗 -->
      <el-dialog
        v-model="dialogB"
        :title="parameterStatus ? '修改规格' : '创建规格'"
        width="700px"
        destroy-on-close
      >
        <el-form
          ref="specificaForm"
          :model="specification"
          :rules="rulesB"
          @submit.prevent
          :label-width="150"
          status-icon
        >
          <el-form-item label="类型名称" prop="title">
            <el-input
              v-model.trim="specification.title"
              @keyup.enter="setSpecifica('specificaForm')"
            />
          </el-form-item>
        </el-form>
        <template #footer>
          <span>
            <el-button @click="dialogB = false">取消</el-button>
            <el-button type="primary" @click="setSpecifica('specificaForm')"
              >{{ parameterStatus ? "修改" : "创建" }}规格</el-button
            >
          </span>
        </template>
      </el-dialog>
    </el-card>
    <!-- 商品（Sku）详情 -->
    <el-card>
      <template #header>
        <el-space direction="vertical" alignment="flex-start">
          <h4>商品（Sku）详情</h4>
          <el-button type="primary" plain @click="dialogC = true"
            >批量定价</el-button
          >
          <el-space
            wrap
            alignment="flex-start"
            v-for="(item, index) in submitData.specificationList"
            :key="item.gmtCreate"
          >
            <el-tag type="warning">{{ item.title }}</el-tag>
            <el-tag
              v-for="tag in item.values"
              :key="tag"
              closable
              :disable-transitions="false"
              @close="handleClose(tag, index)"
            >
              {{ tag }}
            </el-tag>
            <el-input
              v-if="item.inputSkuTagVisible"
              v-model="item.inputSkuTagValue"
              @keyup.enter="handleInputConfirm(index)"
              @blur="handleInputConfirm(index)"
            />
            <el-tag effect="plain" v-else @click="showInput(index)">
              + 添加
            </el-tag>
          </el-space>
        </el-space>
      </template>
      <el-table border :data="submitData.skuList" :span-method="arrayRow">
        <el-table-column
          :label="item.title"
          :prop="'id_' + item.title"
          v-for="item in submitData.specificationList"
          :key="item.gmtCreate"
          align="center"
        >
        </el-table-column>
        <el-table-column label="SkuId" align="center" />
        <el-table-column label="￥价格(元)" align="center" :width="200">
          <template #default="scope" :width="200">
            <el-input-number
              :min="0"
              v-model="scope.row.price"
              :precision="2"
            />
          </template>
        </el-table-column>
        <el-table-column label="￥VIP价(元)" align="center" :width="200">
          <template #default="scope">
            <el-input-number
              :min="0"
              v-model="scope.row.vipPrice"
              :precision="2"
            />
          </template>
        </el-table-column>
        <el-table-column label="￥吊牌价(元)" align="center" :width="200">
          <template #default="scope">
            <el-input-number
              :min="0"
              v-model="scope.row.originalPrice"
              :precision="2"
            />
          </template>
        </el-table-column>
        <el-table-column label="库存(件)" align="center" :width="200">
          <template #default="scope">
            <el-input-number :min="0" v-model="scope.row.stock" />
          </template>
        </el-table-column>
        <el-table-column label="重量(克)" align="center" :width="200">
          <template #default="scope">
            <el-input-number :min="0" v-model="scope.row.weight" />
          </template>
        </el-table-column>
        <el-table-column label="SKU图片" align="center" :width="200">
          <template #default="scope">
            <el-upload
              :show-file-list="false"
              :headers="{ AdminToken: token }"
              :action="action"
              :on-success="handleAvatarSuccess"
            >
              <img
                v-if="scope.row.img"
                :src="scope.row.img"
                style="height: 30px"
              />
              <el-icon v-else :size="20">
                <Upload @click="imgrow = scope.row" />
              </el-icon>
            </el-upload>
          </template>
        </el-table-column>
        <el-table-column label="条形码" align="center" :width="200">
          <template #default="scope">
            <el-input v-model="scope.row.barCode" :readonly="true">
              <template #append>
                <el-button
                  type="info"
                  @click="
                    () => {
                      scope.row.barCode = new Date().getTime();
                    }
                  "
                  >随机</el-button
                >
              </template>
            </el-input>
          </template>
        </el-table-column>
      </el-table>
      <!-- 批量定价弹出框 -->
      <el-dialog
        v-model="dialogC"
        :title="parameterStatus ? '修改规格' : '创建规格'"
        width="500px"
        destroy-on-close
      >
        <el-form
          label-position="left"
          :label-width="100"
          style="margin-left: 100px"
        >
          <el-form-item label="现价(￥)">
            <el-input-number :min="0" v-model="price" :precision="2" />
          </el-form-item>
          <el-form-item label="VIP价格(￥)">
            <el-input-number
              :min="0"
              v-model="vipPrice"
              :precision="2"
              :step="0.1"
            />
          </el-form-item>
          <el-form-item label="吊牌价(￥)">
            <el-input-number :min="0" v-model="originalPrice" :precision="2" />
          </el-form-item>
        </el-form>
        <template #footer>
          <span>
            <el-button @click="dialogC = false">取消</el-button>
            <el-button type="primary" @click="alterAllPrice">确认</el-button>
          </span>
        </template>
      </el-dialog>
    </el-card>
    <div style="margin: 10px 0px; display: flex; justify-content: flex-end">
      <el-button type="info" @click="deleTag">关闭</el-button>
      <el-button type="primary" @click="submitList('formRef')"
        >保存商品</el-button
      >
    </div>
  </div>
</template>

<script>
import { post, action } from "@/utils/http";
import { Plus, Upload } from "@element-plus/icons-vue";
import { mapActions, mapState } from "vuex";
import Cookie from "js-cookie";
import RichText from "@/components/richtext/RichText.vue";
export default {
  components: { Plus, Upload, RichText },
  data() {
    return {
      action: action,
      token: Cookie.get("token"),
      dialogA: false, //参数弹出框
      dialogB: false, //规格维度弹窗
      parameterStatus: 0, //规格维度状态0为创建1为修改
      parameterIndex: 0, //规格维度修改的下标
      dialogC: false, //批量定价的弹出框
      // 在批量定价的弹出框中，用于定义全部的价格
      price: 0, //现价
      vipPrice: 0, //VIP价格
      originalPrice: 0, //吊牌价
      imgrow: {}, //上传图片的行
      imgList: [], //渲染在页面的图片路径
      // 提交需要的数据
      submitData: {
        title: "",
        price: "0",
        originalPrice: "0",
        vipPrice: "0",
        freightTemplateId: null,
        stock: 0, //剩余库存
        status: 1,
        imgList: [],
        img: "",
        unit: "",
        categoryId: null,
        description: "",
        detail: "", //详细介绍
        attributeList: [], //参数列表
        specificationList: [], //维度数据列表
        skuList: [], //详情列表
      },
      attrItem: { attribute: "", value: "" }, //表单参数对象
      specification: {
        gmtCreate: "",
        title: "",
        gmtUpdate: "",
        inputSkuTagValue: "",
        inputSkuTagVisible: false,
        values: [],
      }, //表单维度对象
      categoryList: [], //类目选择的数据
      freightList: [], //运费模板选择的数据
      // 类目级联选择器的配置
      props: {
        label: "title",
        children: "childrenList",
        value: "id",
        emitPath: false,
      },
      // 表单验证规则
      rulesA: {
        title: [{ required: true, message: "请输入商品名称", trigger: "blur" }],
        price: [{ required: true, message: "请输入当前价格", trigger: "blur" }],
        originalPrice: [
          { required: true, message: "请输入原始价格", trigger: "blur" },
        ],
        vipPrice: [
          { required: true, message: "请输入VIP价格", trigger: "blur" },
        ],
        status: [{ required: true }],
        unit: [{ required: true, message: "请输入商品单位", trigger: "blur" }],
        detail: [
          { required: true, message: "请输入商品详细介绍", trigger: "blur" },
        ],
      },
      rulesB: {
        //弹出框的验证规则
        attribute: [
          { required: true, message: "请输入商品参数名称", trigger: "blur" },
        ],
        value: [{ required: true, message: "请输入参数值", trigger: "blur" }],
        title: [{ required: true, message: "请输入类型名称", trigger: "blur" }],
      },
    };
  },
  methods: {
    name: "create",
    ...mapActions(["tabClose"]),
    deleTag() {
      //关闭当前页
      let index = this.tabsList.findIndex(
        (item) => item.name == this.$route.name
      );
      this.tabClose(index);
      this.$router.replace({ name: "productlist" });
    },
    // 跨行计算
    arrayRow({ rowIndex, columnIndex }) {
      let specList = this.submitData.specificationList.filter(
        (i) => i.values.length > 0
      ); //获取规格列表
      if (columnIndex < specList.length - 1) {
        //对要跨行的列进行计算(最后的属性列不计入)
        let rowSpanNum = 1; //跨行的数量
        for (let index = columnIndex + 1; index < specList.length; index++) {
          rowSpanNum *= specList[index].values.length; //累乘获取
        }
        if (rowIndex % rowSpanNum == 0) {
          return { rowspan: rowSpanNum, colspan: 1 };
        } else {
          return { rowspan: 0, colspan: 0 };
        }
      }
    },
    // 笛卡尔积算法
    cartesianProductOf(list) {
      return list.reduce(
        (total, next) => {
          var array = [];
          total.forEach((item) => {
            next.forEach((item2) => {
              array.push(item.concat([item2]));
            });
          });
          return array;
        },
        [[]]
      );
    },
    // 计算skuList
    getSkuList(Val) {
      let cloneNewVal = JSON.parse(JSON.stringify(Val));
      let attrName = []; //规格名数组
      let attrValue = []; //规格值数组
      for (let key in cloneNewVal) {
        if (cloneNewVal[key].length) {
          attrName.push(key);
          attrValue.push(cloneNewVal[key]);
        }
      }
      // 表格内容数据（笛卡尔积算法）
      let finalArr = this.cartesianProductOf(attrValue);
      if (finalArr.flat().length == 0) finalArr = []; //清空数组
      // 表格内容
      this.submitData.skuList = finalArr?.map((item) => {
        let line = this.submitData.skuList.find(
          (v) => v.title == item.join(",")
        ); //查找是否有对应数据
        let obj = {
          price: 0,
          vipPrice: 0,
          originalPrice: 0,
          stock: 0,
          barCode: "",
          weight: null,
          img: "",
          title: item.join(","),
          specification: "",
        };
        obj = line ? Object.assign(obj, line) : obj;
        for (let i = 0; i < item.length; i++) {
          obj["id_" + attrName[i]] = item[i];
          obj.specification += attrName[i] + "_" + item[i] + ",";
        }
        return obj;
      });
    },
    // 请求类目列表
    getCategory() {
      if (this.categoryList.length) return; //在没有类目数据的时候请求
      post({ _gp: "admin.category", _mt: "categoryTree" }).then((res) => {
        if (200 == res?.errno) {
          //成功状态码
          this.categoryList = res.data;
        }
      });
    },
    // 请求运费模板
    getFreight() {
      if (this.freightList.length) return;
      post({ _gp: "admin.freight", _mt: "list" }).then((res) => {
        if (200 == res?.errno) {
          //成功状态码
          this.freightList = res.data;
        }
      });
    },
    // 添加参数
    addParameter(formEl) {
      this.$refs[formEl].validate((valid) => {
        if (valid) {
          this.submitData.attributeList.push({ ...this.attrItem });
          ElMessage.success("设置成功");
          this.dialogA = false;
        }
      });
    },
    // 删除参数
    deleParameter(index) {
      ElMessageBox.confirm("是否删除本行参数?", "提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.submitData.attributeList.splice(index, 1);
          ElMessage.success("删除参数成功");
        })
        .catch(() => {
          ElMessage.info("删除取消");
        });
    },
    // 提交规格(添加和修改)
    setSpecifica(formEl) {
      this.$refs[formEl].validate((valid) => {
        if (valid) {
          let nowDate = new Date().getTime(); //获取当前时间
          this.specification.gmtUpdate = nowDate;
          this.specification.gmtCreate = nowDate;
          if (!this.parameterStatus) {
            this.submitData.specificationList.push({ ...this.specification });
            ElMessage.success("创建规格成功");
            this.dialogB = false;
            return;
          }
          // 获取列表中对应的行，把表单中的数据克隆给该行
          Object.assign(
            this.submitData.specificationList[this.parameterIndex],
            this.specification
          );
          ElMessage.success("修改规格成功");
          this.dialogB = false;
        }
      });
    },
    // 删除规格
    delelSpecifica(index) {
      ElMessageBox.confirm("是否删除本行规格?", "提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.submitData.specificationList.splice(index, 1);
          ElMessage.success("删除规格成功");
        })
        .catch(() => {
          ElMessage.info("删除取消");
        });
    },
    // 显示添加规格值的输入框
    showInput(index) {
      this.submitData.specificationList[index].inputSkuTagVisible = true;
    },
    // 添加规格值tag
    handleInputConfirm(index) {
      let list = this.submitData.specificationList[index];
      if (list.inputSkuTagValue) {
        //不为空
        list.values.push(list.inputSkuTagValue); //添加标签
        this.getSkuList(this.calculateAttribute); //计算表格
      }
      list.inputSkuTagValue = ""; //清空输入框
      list.inputSkuTagVisible = false; //隐藏输入框
    },
    // 关闭规格值tag
    handleClose(tag, index) {
      let { values } = this.submitData.specificationList[index];
      values.splice(values.indexOf(tag), 1);
      this.getSkuList(this.calculateAttribute); //计算表格
    },
    // 确认批量修改
    alterAllPrice() {
      let { price, vipPrice, originalPrice } = this;
      this.submitData.skuList.forEach((item) =>
        Object.assign(item, { price, vipPrice, originalPrice })
      );
      this.dialogC = false; //关闭定价弹窗
    },
    // 表单图片上传成功
    handleSuccess(response, uploadFile, uploadFiles) {
      if (200 == response.errno) {
        this.submitData.imgList = uploadFiles.map((i) => i.response.url);
        this.submitData.img = this.submitData.imgList[0];
      }
    },
    //表单图片删除成功
    handleRemove(uploadFile, uploadFiles) {
      this.submitData.imgList = uploadFiles.map((i) => i.response.url);
      this.submitData.img = this.submitData.imgList[0];
    },
    // 表格图片上传成功后
    handleAvatarSuccess(response) {
      if (200 == response?.errno) {
        this.imgrow.img = response.url; //获取图片路径
      }
    },
    // 提交表单
    submitList(formEl) {
      this.$refs[formEl].validate((valid) => {
        if (valid) {
          console.log(this.submitData);
          let spuDTO = JSON.stringify({ ...this.submitData });
          ElMessageBox.confirm("是否确认提交商品?", "提示", {
            confirmButtonText: "确认",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              let obj = { _gp: "admin.product", _mt: "create", spuDTO };
              post(obj).then((res) => {
                if (200 == res?.errno) {
                  ElMessage.success("添加商品成功");
                  this.deleTag(); //关闭当前页，跳转到商品列表
                }
              });
            })
            .catch(() => {
              ElMessage.info("取消操作~");
            });
        }
      });
    },
  },
  watch: {
    dialogA(n) {
      //监听参数弹出框
      if (!n) Object.assign(this.attrItem, { attribute: "", value: "" });
    },
    dialogB(n) {
      //监听规格弹出框
      if (!n)
        Object.assign(this.specification, {
          gmtCreate: "",
          title: "",
          gmtUpdate: "",
          inputSkuTagValue: "",
          inputSkuTagVisible: false,
          values: [],
        });
    },
    dialogC(n) {
      //监听定价弹出框
      if (!n) Object.assign(this, { price: 0, vipPrice: 0, originalPrice: 0 });
    },
    // 监听规格数据
    calculateAttribute(newVal) {
      this.getSkuList(newVal);
    },
  },
  computed: {
    ...mapState({
      tabsList: (store) => store.tagpage.tabsList, //用户数据
    }),
    // 计算规格
    calculateAttribute() {
      // 初始化
      let obj = {};
      this.submitData.specificationList.forEach((item) => {
        //规格名:规格值     //'颜色':'尺寸'
        obj[item.title] = item.values;
      });
      return obj;
    },
  },
};
</script>

<style></style>
